﻿package  
{
	import Base.Sound.SoundManager;
	
	import Common.GameDefine;
	import Common.GameLoading;
	import Common.RenderManager;
	
	import Events.LogicEvent;
	import Events.LogicEventManager;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	
	import map.MapGrid;
	import map.PathFinder;
	
	import ui.MapUIHandler;
	
	/**
	 * ...
	 * @author fox
	 */
	public class MapManager 
	{
		public var mapScenes:Object = null;
		
		private var streamData:URLStream = null;
		private var streamXML:URLStream = null;
		//private var loaderNPCXML:URLLoader = null;
		
		public var activeMapData:Object = null;
		
		public var mapData:Object = null;
		public var bmpData:Object = null;
		public var loaderData:Object = null;
		public var mapInfoData:Object = null;
		
		public var mapID:int = 0;
		public var loadNum:int = 0;
		public var maxLoadNum:int = 0;
		public var loadXMLNum:int = 0;
		public var isLoaded:Boolean = false;
		
		public function MapManager() 
		{
			mapScenes = new Object();
		}
		
		public function init():void
		{
			mapData = new Object();
			bmpData = new Object();
			loaderData = new Object();
			mapInfoData = new Object();
			
			streamData = new URLStream();
			streamXML = new URLStream();
			//loaderNPCXML = new URLLoader();
			
			streamData.addEventListener( Event.COMPLETE , onDataComplete );
			streamData.addEventListener( IOErrorEvent.IO_ERROR , onError );
			streamData.addEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
			streamXML.addEventListener( Event.COMPLETE , onXMLComplete );
			streamXML.addEventListener( IOErrorEvent.IO_ERROR , onError1 );
			streamXML.addEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
//			loaderNPCXML.addEventListener( Event.COMPLETE , onNPCXMLComplete );
//			loaderNPCXML.addEventListener( IOErrorEvent.IO_ERROR , onError );
//			loaderNPCXML.addEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
		}
		
		public function release():void
		{
			
		}
		
		public static var instance:MapManager = null;
		public static function Instance():MapManager
		{
			if ( instance == null )
			{
				instance = new MapManager();
			}
			
			return instance;
		}
		
		public function onLoadTexture1( e:Event  ):void
		{
			var image:Bitmap = Bitmap( e.target.content );
			
			var id:int = int( e.target.loader.name );
			
			bmpData[ id ] = image.bitmapData;
			
			loadNum--;
			
			
			loaderData[ id ].contentLoaderInfo.removeEventListener( Event.COMPLETE , onLoadTexture1 );
			loaderData[ id ].unload();
			loaderData[ id ] = null;
			delete loaderData[ id ];
			
			if ( loadNum == 0 ) 
			{
				loaded();
			}
			
			if ( maxLoadNum && loadNum >= 0 )
				GameLoading.instance.loading( "" , 100 * ( Number( maxLoadNum - loadNum ) / Number( maxLoadNum ) ) );
			else
				GameLoading.instance.loading( "" , 100 );
		}
		
		public function onLoadTexture2( e:Event  ):void
		{
			var id:int = int( e.target.loader.name );
			var image:Bitmap = Bitmap( e.target.content );
				
			bmpData[ id ] = image.bitmapData;
			
			loaderData[ id ].contentLoaderInfo.removeEventListener( Event.COMPLETE , onLoadTexture2 );
			loaderData[ id ].unload();
			loaderData[ id ] = null;
			delete loaderData[ id ];
			
			SceneManager.instance.redraw();
		}
		
		
		public function isBlock( x:int , y:int ):Boolean
		{
			var n:int = int( activeMapData.mapBlockData.substr( y * activeMapData.x + x , 1 ) );
			
			if ( n == GameDefine.BLOCK || n == GameDefine.BLOCK + GameDefine.SHADOW ) 
			{
				return true;
			}
			
			return false;
		}
		
//		public function isNpc( x:int , y:int ):int
//		{
//			if ( activeMapData.building[ y ] ) 
//			{
//				if ( activeMapData.building[ y ][ x ] ) 
//				{
//					if ( activeMapData.building[ y ][ x ].npcID != null ) 
//					{
//						return activeMapData.building[ y ][ x ].npcID;
//					}
//				}
//			}
//			
//			return GameDefine.INVALIDID;
//		}
		
		public function loadTextureT( x:int , y:int ):void
		{
			var mapGrid:MapGrid = GameManager.instance.MainPlayer.MMapGrid;
			
			if ( !bmpData[ activeMapData.terrain[y][x].id ] && !loaderData[ activeMapData.terrain[y][x].id ] ) 
			{
				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture2 );
				loader.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + activeMapData.terrain[y][x].id +".png" ) );
				loader.name = activeMapData.terrain[y][x].id.toString();
				
				loaderData[ activeMapData.terrain[y][x].id ] = loader;
			}
			
			mapGrid = null;
		}
		
		public function loadTextureB( id:int ):void
		{
			if ( !bmpData[ id ] && !loaderData[ id ] ) 
			{
				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture2 );
				loader.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + id +".png" ) );
				loader.name = id.toString();
				
				loaderData[ id ] = loader;
			}
		}
		
		
		private function onDataComplete( e:Event ):void
		{
			var fileData:ByteArray = new ByteArray();
			streamData.readBytes( fileData , 0 , streamData.bytesAvailable );
			fileData.uncompress();
			
			var fileHead:ByteArray = new ByteArray();
			fileData.readBytes( fileHead , 0 , 6 );
			
			activeMapData.id = fileData.readShort();
			activeMapData.name = fileData.readMultiByte( 32 , "gb2312" );
			var a:Array = activeMapData.name.split( '|' );
			activeMapData.name = a[ 0 ];
			
			activeMapData.x = fileData.readShort();
			activeMapData.y = fileData.readShort();
			activeMapData.terrain = new Object();
			activeMapData.building = new Object();
			
			MapUIHandler.instance.updatePos();
			MapUIHandler.instance.updateName();
			
			
			loadNum = 0;
			
			//loaderData = null;
			//loaderData = new Object();
			
			var mapGrid:MapGrid = GameManager.instance.MainPlayer.MMapGrid;
			
			var i:int = 0;
			var j:int = 0
			var id:int = 0;
			for ( i = 0; i < activeMapData.y ; i++) 
			{
				activeMapData.terrain[i] = new Object();
				for ( j = 0; j < activeMapData.x; j++ ) 
				{
					activeMapData.terrain[i][j] = new Object();
					activeMapData.terrain[i][j].id = fileData.readShort();
										
					if ( ( mapGrid.x - j ) < SceneManager.instance.sceneHalfX && ( mapGrid.y - i ) < SceneManager.instance.sceneHalfY 
						&& ( j - mapGrid.x ) < SceneManager.instance.sceneHalfX && ( i - mapGrid.y ) < SceneManager.instance.sceneHalfY
						&& !bmpData[ activeMapData.terrain[i][j].id ] && !loaderData[ activeMapData.terrain[i][j].id ] ) 
					{
						var loader:Loader = new Loader();
						loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture1 );
						loader.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + activeMapData.terrain[i][j].id +".png" ) );
						loader.name = activeMapData.terrain[i][j].id.toString();
						
						loaderData[ activeMapData.terrain[i][j].id ] = loader;
						
						loadNum++;
					}
					
				}
			}
			
//			for ( i = 0; i < activeMapData.y ; i++) 
//			{
//				for ( j = 0; j < activeMapData.x; j++ ) 
//				{
//					if ( !bmpData[ activeMapData.terrain[i][j].id ] && !loaderData[activeMapData.terrain[i][j].id] ) 
//					{
//						var loader1:Loader = new Loader();
//						
//						loader1.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture1 );
//						loader1.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + activeMapData.terrain[i][j].id +".png" ) );
//						loader1.name = activeMapData.terrain[i][j].id.toString();
//						
//						loaderData[ activeMapData.terrain[i][j].id ] = loader1;
//						
//						//loadNum++;
//					}
//					
//				}
//			}
			
			maxLoadNum = loadNum;
						
			var index:int = 0;
			for ( i = 0; i < activeMapData.y ; i++) 
			{
				activeMapData.building[i] = new Object();
				for ( j = 0; j < activeMapData.x ; j++ ) 
				{
					id = fileData.readShort();
					
					if ( id == 0  ) 
					{
						continue;
					}
					
					
					var buildX:int = j;
					var buildY:int = i;
					
					var s:int = mapInfoData[id].s;
					var ee:int = mapInfoData[id].e;
					var f:int = mapInfoData[id].f;
					
					
					for (var k:int = 0; k < s; k++) 
					{
						for (var l:int = 0; l < ee; l++) 
						{
							activeMapData.building[ buildY - k ][ buildX + l ] = new RenderObject();
							activeMapData.building[ buildY - k ][ buildX + l ].renderID = id;
							activeMapData.building[ buildY - k ][ buildX + l ].renderE = l;
							activeMapData.building[ buildY - k ][ buildX + l ].renderS = k;
							activeMapData.building[ buildY - k ][ buildX + l ].renderIndex = index;
						}
					}
					
					index++;
					
				}
			}
			
			GameLoading.instance.loading( "" , 99 );
			
			if ( loadNum == 0 ) 
			{
				loaded();
			}
			
			streamData.close();
			
			trace( activeMapData.x , activeMapData.y );
			
			
			activeMapData.mapBlockData = new String();
			
			for ( i = 0; i < activeMapData.y ; i++) 
			{
				for ( j = 0; j < activeMapData.x; j++) 
				{
					var block:String = "";
					
					id = activeMapData.terrain[ i ][ j ].id;
					if ( mapInfoData[ id ].f == 1 ) 
					{
						block = "0";
					}
					else
					{
						block = "1";
					}
					
					
					if ( activeMapData.building[i][j] ) 
					{
						id = activeMapData.building[ i ][ j ].renderID;
						
						if ( id == 2 ) 
						{
							activeMapData.mapBlockData += "1";
							continue;
						}
						
						f = mapInfoData[id].f;
						
						if ( f == 1 || f == 45 || f == 46 ) 
						{
							block = "0";
						}
						else
						{
							block = "1";
						}
					}
					
					activeMapData.mapBlockData += block;
				}
				
			}
			
			PathFinder.instance.initMap( activeMapData.mapBlockData , activeMapData.x , activeMapData.y );
			
			mapData[ mapID ] = activeMapData;
			
			//loaderNPCXML.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "npc/" + mapID.toString() + ".xml" ) );
			
			mapGrid = null;
		}
		
		public function loaded():void
		{
			isLoaded = true;
			
			if ( activeMapData.sound ) 
			{
				SoundManager.instance.Load( GameDefine.PATH1 + activeMapData.sound );
				SoundManager.instance.PlayMusic( GameDefine.PATH1 + activeMapData.sound );
			}
			
			GameLoading.instance.unload();
			
			
			var mapGrid:MapGrid = GameManager.instance.MainPlayer.MMapGrid;
			var index:int = 0;
			for ( var i:int = 0; i < activeMapData.y ; i++) 
			{
				for ( var j:int = 0; j < activeMapData.x ; j++ ) 
				{
					if ( !activeMapData.building[ i ][ j ] )
						continue;
					
					var id:int = activeMapData.building[ i ][ j ].renderID;
					
					if ( id == 0  ) 
					{
						continue;
					}
					
					if ( ( mapGrid.x - j ) < SceneManager.instance.sceneHalfX && ( mapGrid.y - i ) < SceneManager.instance.sceneHalfY 
						&& ( j - mapGrid.x ) < SceneManager.instance.sceneHalfX && ( i - mapGrid.y ) < SceneManager.instance.sceneHalfY
						&& !bmpData[ id ] && !loaderData[ id ] ) 
					{
						var loader:Loader = new Loader();
						loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture2 );
						loader.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + id +".png" ) );
						loader.name = id.toString();
						
						loaderData[ id ] = loader;
					}
					
				}
			}
			
			
			
			mapGrid = null;
		}
		
		private function onError( e:IOErrorEvent ):void
		{
			GameLoading.instance.loading( e.toString() , 12 );
		}
		
		private function onError1( e:IOErrorEvent ):void
		{
			GameLoading.instance.loading( e.toString() , 11 );
		}
		
		private function onSecurityError( e:SecurityErrorEvent ):void
		{
			GameLoading.instance.loading( e.toString() , 0 );
		}
		
		
//		private function onNPCXMLComplete( e:Event ):void
//		{
//			var xml:XML = XML( e.target.data );
//			var id:int = int( xml.@id );
//			var index:int = 100000;
//			
//			for each ( var element:XML in xml.elements() ) 
//			{
//				var x:int = int( element.@x );
//				var y:int = int( element.@y );
//				var t:int = int( element.@t );
//				
//				mapData[ id ].building[ y ][ x ] = new Object();
//				mapData[ id ].building[ y ][ x ].id = t;
//				mapData[ id ].building[ y ][ x ].npcID = int( element.@id );
//				mapData[ id ].building[ y ][ x ].e = 0;
//				mapData[ id ].building[ y ][ x ].s = 0;
//				mapData[ id ].building[ y ][ x ].index = index;
//				
//				mapInfoData[ t ] = new Object();
//				mapInfoData[ t ].px = int( element.@px );
//				mapInfoData[ t ].py = int ( element.@py );
//				mapInfoData[ t ].f = 1;
//				mapInfoData[ t ].e = 1;
//				mapInfoData[ t ].s = 1;
//				
//				index++;
//				
//				if ( !bmpData[ t ] && !loaderData[ t ] ) 
//				{
//					var loader:Loader = new Loader();
//					
//					loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture2 );
//					loader.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + t +".png" ) );
//					loader.name = t.toString();
//					
//					loaderData[ t ] = loader;
//				}
//				
//			}
//			
//			
//		}
		
		private function onXMLComplete( e:Event ):void
		{
			var fileData:ByteArray = new ByteArray();
			e.target.readBytes( fileData , 0 , e.target.bytesAvailable );
			fileData.uncompress();
			
			var xml:XML = XML( fileData );
			var path:String =  xml.@sound; 
			
			activeMapData = null;
			activeMapData = new Object();
			
			if ( path.length )
			{
				activeMapData.sound = xml.@sound;
			}
			
			for each ( var element:XML in xml.elements() ) 
			{
				mapInfoData[element.@id] = new Object();
				mapInfoData[element.@id].px = int( element.@px );
				mapInfoData[element.@id].py = int ( element.@py );
				mapInfoData[element.@id].f = int( element.@f );
				
				var ee:int = element.@e;
				if ( ee )
				{
					mapInfoData[element.@id].e = int ( element.@e );
					mapInfoData[element.@id].s = int ( element.@s );
				}
			}
			
			fileData.clear();
			fileData = null;
			
			streamXML.close();
			
			loadXMLNum--;
			streamData.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "map/" + xml.@id + ".mapc") );
			
			xml = null;
		}
		
		public function Load( id:int ):void
		{
			mapID = id;
			
			if ( mapData[ mapID ] ) 
			{
				// 切换速度太快了。做个读取的。
				activeMapData = mapData[ mapID ];
				PathFinder.instance.initMap( activeMapData.mapBlockData , activeMapData.x , activeMapData.y );
				
				if ( activeMapData.sound ) 
				{
					SoundManager.instance.PlayMusic( GameDefine.PATH1 + activeMapData.sound );
				}
				
				MapUIHandler.instance.updatePos();
				MapUIHandler.instance.updateName();
				
				return;
			}
			
			loadXMLNum = 1;
			loadNum = -1;
			
			streamXML.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "map/" + id.toString() + ".xmlc" ) );
			
			isLoaded = false;
			
			GameLoading.instance.load();
			GameLoading.instance.loading( "" , 0 );
		}
	}
	
}

